package com.dongnao.network.netty_groupchat;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.socket.SocketChannel;
import io.netty.util.CharsetUtil;

import java.util.ArrayList;
import java.util.List;

/**
 * 群聊系统
 * 1)实现多人群聊
 * 2)服务器端:可以监测用户上线，离线，并实现消息转发功能
 * 3)客户端:通过channel可以无阻塞发送消息给其它所有用户，同时可以接受其它用户发送的消息(有服务器转发得到)
 */
public class NettyServerHandler extends ChannelInboundHandlerAdapter {
    static int onLinePeople;
    static List<SocketChannel> socketChannelList = new ArrayList<>();

    //通道连接就绪触发连接就绪方法，配合连接关闭可以用于统计在线人数
    @Override
    public void channelActive(ChannelHandlerContext ctx) {
        onLinePeople += 1;
        System.out.println("地址：" + ctx.channel().remoteAddress() + "用户上线");
        System.out.println("当前在线人数为：" + onLinePeople);
        SocketChannel channel = (SocketChannel) ctx.channel();
        socketChannelList.add(channel);
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) {
        onLinePeople -= 1;
        System.out.println("地址：" + ctx.channel().remoteAddress() + "用户下线");
        System.out.println("当前在线人数为：" + onLinePeople);

        //移除下线的客户端通道
        SocketChannel channel = (SocketChannel) ctx.channel();
        for (SocketChannel socketChannel : socketChannelList) {
            if (channel.equals(socketChannel)) {
                socketChannelList.remove(socketChannel);
            }
        }
    }

    //读取数据
    /*
    1. ChannelHandlerContext ctx:上下文对象，含有管道pipeline，通道channel，地址
    2. Object msg:就是客户端发送的数据默认 Object
    */
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) {
        //将任务提交到与 Channel 相关联的事件循环（EventLoop）中执行
        ctx.channel().eventLoop().execute(new Runnable() {
            @Override
            public void run() {
                //读取客户端发送的消息
                ByteBuf buf = (ByteBuf) msg;
                String s = buf.toString(CharsetUtil.UTF_8);
                System.out.println("客户端地址" + ctx.channel().remoteAddress() + "用户发消息" + s);

                //转发给其他客户端
                SocketChannel channel = (SocketChannel) ctx.channel();
                if (socketChannelList.size() > 1) {
                    //排除自己给其他客户端发消息
                    for (SocketChannel socketChannel : socketChannelList) {
                        if (!channel.equals(socketChannel)) {
                            socketChannel.writeAndFlush(Unpooled.copiedBuffer(s, CharsetUtil.UTF_8));
                        }
                    }
                }
            }
        });
    }

//    //数据读取完毕
//    @Override
//    public void channelReadComplete(ChannelHandlerContext ctx){
//        //writeAndFlush是 write + flush
//        //将数据写入缓存并刷新
//        //一般要对发送数据进行编码
//        ctx.writeAndFlush(Unpooled.copiedBuffer("hello 客户端酱",CharsetUtil.UTF_8));
//    }

    //异常处理
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        ctx.close();
    }

}
